#include "uart_driver.h"

static QueueHandle_t uart1_queue;
static QueueHandle_t uart2_queue;


static TaskHandle_t uart1_task_handle;
static TaskHandle_t uart2_task_handle;

UART_FUNC uart_func_handle;

void uart1_msg_send(uint8_t* buf,uint8_t length)
{    
    uart_write_bytes(UART_NUM1, (const uint8_t *)buf, length);
}

void uart2_msg_send(uint8_t* buf,uint8_t length)
{    
    uart_write_bytes(UART_NUM2, (const uint8_t *)buf, length);
}

void uart1_config(int tx_io_num, int rx_io_num,uint32_t baud_rate, bool use_ref_tick)
{
    uart_config_t uart_config = {
        .baud_rate = baud_rate,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };

    uart_intr_config_t uart_intr = {
    .intr_enable_mask = (0x1<<0) | (0x1<<8),
    .rxfifo_full_thresh = 100,
    .rx_timeout_thresh = 100,
    };

    uart_param_config(UART_NUM1, &uart_config); //串口配置
    uart_set_pin(UART_NUM1, tx_io_num, rx_io_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //串口初始化
    uart_driver_install(UART_NUM1, UART_BUFFER_SIZE*2, UART_BUFFER_SIZE*2, 10, &uart1_queue, ESP_INTR_FLAG_LOWMED); //低优先级的中断
    uart_intr_config(UART_NUM1, &uart_intr);
    // Enable UART RX FIFO full threshold and timeout interrupts
    uart_enable_rx_intr(UART_NUM1);

}

void uart2_config(int tx_io_num, int rx_io_num,uint32_t baud_rate, bool use_ref_tick)
{
    uart_config_t uart_config = {
        .baud_rate = baud_rate,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };

    uart_param_config(UART_NUM2, &uart_config); //串口配置
    uart_set_pin(UART_NUM2, tx_io_num, rx_io_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //串口初始化
    uart_driver_install(UART_NUM2, UART_BUFFER_SIZE*2, UART_BUFFER_SIZE*2, 10, &uart2_queue, ESP_INTR_FLAG_LOWMED); //低优先级的中断
}


void set_uart1_handle_func(void (*uart_func)(uart_port_t,size_t))
{
    uart_func_handle.uart1_func =uart_func;
}


static void uart1_event_task(void *pvParameters)
{
    uart_event_t event;
    for (;;) 
    {
        if (xQueueReceive(uart1_queue, (void *)&event, (TickType_t)portMAX_DELAY)) 
        {
            switch (event.type) 
            {
                case UART_DATA:
                    if (event.timeout_flag)//发生超时。说明数据全部接收完成，可以开始处理了
                    {
                        uart_func_handle.uart1_func(UART_NUM1,event.size);
                    }
                    break;
                //Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    printf("hw fifo overflow\n");
                    uart_flush_input(UART_NUM1);
                    xQueueReset(uart1_queue);
                    break;
                //Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    printf("ring buffer full");
                    uart_flush_input(UART_NUM1);
                    xQueueReset(uart1_queue);
                    break;
                //Event of UART RX break detected
                case UART_BREAK:
                    printf("uart rx break");
                    break;
                //Event of UART parity check error
                case UART_PARITY_ERR:
                    printf("uart parity error");
                    break;
                //Event of UART frame error
                case UART_FRAME_ERR:
                    printf("uart frame error");
                    break;
                //Others
                default:
                    printf("uart event type: %d\n", event.type);
                    break;
            }
        }
    }
}


void uart1_init() //串口任务初始化
{
    printf("uart1_init():enter");
    xTaskCreate(uart1_event_task, "uart_queue_task", UART_SZIE, NULL, TASK_PROP_UART, &uart1_task_handle);
}

void set_uart2_handle_func(void (*uart_func)(uart_port_t,size_t))
{
    uart_func_handle.uart2_func = uart_func;
}

static void uart2_event_task(void *pvParameters)
{
    uart_event_t event;
    for (;;) 
    {
        if (xQueueReceive(uart2_queue, (void *)&event, (TickType_t)portMAX_DELAY)) 
        {
            switch (event.type) 
            {
                case UART_DATA:
                    uart_func_handle.uart2_func(UART_NUM2,event.size);
                    break;
                case UART_FIFO_OVF:
                    printf("hw fifo overflow\n");
                    uart_flush_input(UART_NUM2);
                    xQueueReset(uart2_queue);
                    break;
                case UART_BUFFER_FULL:
                    printf("ring buffer full");
                    uart_flush_input(UART_NUM2);
                    xQueueReset(uart2_queue);
                    break;
                case UART_BREAK:
                    printf("uart rx break");
                    break;
                case UART_PARITY_ERR:
                    printf("uart parity error");
                    break;
                case UART_FRAME_ERR:
                    printf("uart frame error");
                    break;
                default:
                    printf("uart event type: %d\n", event.type);
                    break;
            }
        }
    }
}


void uart2_init() //串口任务初始化
{
    printf("device_uart2_int():enter");
    xTaskCreate(uart2_event_task, "uart2_init", 4096, NULL, TASK_PROP_UART, &uart2_task_handle);
}